﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Flight
{
    public class Person
    {
        private Vector3 loc;
        private Vector3 vel;
        private float viewHeading, viewPitch;

        public readonly float CAMERA_HEIGHT;
        public readonly float WALK_SPEED;
        public readonly float AIR_FRICTION;
        public readonly float JUMP_VEL;
        public readonly float FIELD_OF_VIEW;

        private float effectiveTerrainHeight;

        public Person(Vector3 loc, Vector3 vel, float viewHeading, float viewPitch)
        {
            Settings settings = new Settings("person-settings.txt");

            this.loc = loc;
            this.vel = vel;
            this.viewHeading = viewHeading;
            if (viewPitch < 90)
                this.viewPitch = -viewPitch;
            else if (viewPitch < 270)
            {
                this.viewHeading = -this.viewHeading;
                this.viewPitch = 180 - viewPitch;
            }
            else
            {
                this.viewPitch = viewPitch - 360;
            }

            this.CAMERA_HEIGHT = settings.get<float>("camera-height");
            this.WALK_SPEED = settings.get<float>("walk-speed");
            this.AIR_FRICTION = settings.get<float>("air-friction");
            this.JUMP_VEL = settings.get<float>("jump-vel");
            this.FIELD_OF_VIEW = settings.get<float>("field-of-view");

            effectiveTerrainHeight = 0;
        }

        public void update(float frameTime)
        {
            float mdiffX = Mouse.GetState().X - FlightGame.game.width / 2f,
                  mdiffY = Mouse.GetState().Y - FlightGame.game.height / 2f;

            this.viewHeading -= mdiffX / 6;
            this.viewPitch -= mdiffY / 6;

            this.viewPitch = MathHelper.Clamp(this.viewPitch, -89.9f, 89.9f);

            //Vector3 viewDir = Game.degSphere(viewHeading, viewPitch, 1);
            Vector3 viewFront = new Vector3(
                (float)Math.Cos(MathHelper.ToRadians(viewHeading)),
                (float)Math.Sin(MathHelper.ToRadians(viewHeading)),
                0);
            Vector3 viewBack = -viewFront;
            Vector3 viewLeft = new Vector3(
                (float)Math.Cos(MathHelper.ToRadians(viewHeading + 90)),
                (float)Math.Sin(MathHelper.ToRadians(viewHeading + 90)),
                0);
            Vector3 viewRight = -viewLeft;

            vel.Z -= FlightGame.GRAVITY * frameTime;
            vel -= vel * AIR_FRICTION * frameTime;
            loc += vel * frameTime;

            if (Key.isPressed(Keys.R))
                effectiveTerrainHeight += 10 * frameTime;
            if (Key.isPressed(Keys.F))
                effectiveTerrainHeight -= 10 * frameTime;
            if (effectiveTerrainHeight < 0) effectiveTerrainHeight = 0;

            bool onGround = loc.Z <= effectiveTerrainHeight;
            if (loc.Z < effectiveTerrainHeight) loc.Z = effectiveTerrainHeight;

            if (onGround)
                vel = Vector3.Zero;

            if (onGround && Key.isPressed(Keys.Space))
                vel.Z += JUMP_VEL;
            Vector3 movementVel = Vector3.Zero;
            if (Key.isPressed(Keys.A))
                movementVel += viewLeft * WALK_SPEED;
            if (Key.isPressed(Keys.D))
                movementVel += viewRight * WALK_SPEED;
            if (Key.isPressed(Keys.W))
                movementVel += viewFront * WALK_SPEED;
            if (Key.isPressed(Keys.S))
                movementVel += viewBack * WALK_SPEED;
            if (Key.isPressed(Keys.C))
                movementVel *= 10;
            loc += movementVel;

            //if (!Key.isPressed('f'))
            // keep mouse in center
            Mouse.SetPosition(
                FlightGame.game.Window.ClientBounds.Width / 2,
                FlightGame.game.Window.ClientBounds.Height / 2);
        }

        public Vector3 getLoc() { return loc; }
        public float getHeading() { return viewHeading; }
        public float getPitch() { return viewPitch; }
    }
}
